package com.aleyn.router.core

import android.content.Context
import android.os.Handler
import android.os.Looper
import com.aleyn.router.data.InitializerData
import com.aleyn.router.data.InterceptorData
import com.aleyn.router.executor.DefaultPoolExecutor
import com.aleyn.router.inject.Core
import com.aleyn.router.inject.ILRouterGenerate
import com.google.gson.Gson
import java.util.TreeSet
import java.util.concurrent.ExecutorService

/**
 * @author: Aleyn
 * @date: 2023/7/10 16:12
 *
 * LRouter 框架的核心控制器。
 * 这是一个内部单例对象，负责管理整个路由框架的初始化、线程调度、
 * 路由表、拦截器以及全局导航回调等核心组件。
 */

/** 全局 Gson 实例，用于参数序列化 */
val routerGson = Gson()

internal object RouterController {

    /** 线程池，用于执行异步任务，默认为 [DefaultPoolExecutor] */
    private var executor: ExecutorService = DefaultPoolExecutor()

    /** 主线程 Handler，用于在主线程执行任务 */
    private val main = Handler(Looper.getMainLooper())

    /** 路由表，存储所有路由信息 */
    internal val ROUTER_MAP = LRouterMap()

    /** 全局拦截器集合，使用 TreeSet 保证按优先级排序 */
    internal val routerInterceptors = TreeSet<InterceptorData>()

    /** 初始化器模块集合，用于在应用启动时自动初始化 */
    private val initializerModule = TreeSet<InitializerData>()

    /** 全局导航回调 */
    internal var navCallback: NavCallback? = null

    /**
     * 通过反射懒加载 LRouter 的生成类。
     * 这个类是由 KSP 在编译时生成的，包含了所有路由、拦截器和初始化器的注册信息。
     */
    internal val routerGenerate: ILRouterGenerate by lazy {
        Class.forName("com.router.LRouterGenerateImpl")
            .newInstance() as ILRouterGenerate
    }

    /**
     * 设置自定义的线程池。
     * @param e 自定义的 ExecutorService 实例。
     */
    fun setThreadPoolExecutor(e: ExecutorService?) = e?.let {
        executor = it
    }

    /**
     * 异步执行任务。
     * @param runnable 要执行的 Runnable。
     */
    internal fun async(runnable: Runnable) {
        try {
            executor.execute(runnable)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 在主线程执行任务。
     * 如果当前已经是主线程，则直接执行；否则，通过 Handler post 到主线程队列。
     * @param runnable 要执行的 Runnable。
     */
    internal fun main(runnable: Runnable) {
        if (Thread.currentThread() == Looper.getMainLooper().thread) {
            runnable.run()
        } else {
            main.post(runnable)
        }
    }

    /**
     * LRouter 的核心初始化方法。
     * 1. 注册所有模块的初始化器。
     * 2. 根据配置（同步/异步）执行每个初始化器的 create 方法。
     * 3. 清空初始化器列表，防止重复执行。
     * 4. 异步加载所有模块的路由表和拦截器。
     * 5. 触发依赖注入框架的预加载。
     *
     * @param context ApplicationContext。
     */
    internal fun init(context: Context) {
        // 注册所有初始化器
        routerGenerate.registerAllInitializer()
        // 执行各模块初始化器
        initializerModule.forEach {
            if (it.async) {
                async { it.routerInitializer.create(context) }
            } else {
                it.routerInitializer.create(context)
            }
        }
        initializerModule.clear()
        // 异步注册路由和拦截器信息
        async {
            routerGenerate.initModuleRouter()
            routerGenerate.registerIntercept()
            Core.createEagerInstances()
        }
    }

    /**
     * 注册初始化器。
     * 由编译时生成的代码调用，将各模块的初始化器添加到集合中。
     *
     * @param priority 优先级，值越小优先级越高。
     * @param async 是否异步执行。
     * @param initializer 初始化器实例。
     */
    @JvmStatic
    fun registerInitializer(
        priority: Byte,
        async: Boolean,
        initializer: LRouterInitializer
    ) {
        initializerModule.add(InitializerData(priority, async, initializer))
    }

}